package nrd;

import robocode.BulletHitEvent;
import robocode.BulletMissedEvent;
import robocode.HitByBulletEvent;
import robocode.HitRobotEvent;
import robocode.Robot;
import robocode.ScannedRobotEvent;
import robocode.WinEvent;
import java.awt.Color;

/**
 * This robot attempts to scan for and fire at robots while making small movements that do not
 * happen every cycle to make them seem less obvious.
 * 
 * @author Nathan Dorman
 */
public class TheOrangeRobot extends Robot {

  // distances of battlefield
  double across = 0;
  double width = 0;
  double height = 0;

  // track bullets fired and received
  int myHitCount = 0;
  int myMissCount = 0;
  int hitCount = 0;

  // movement and direction counters
  int countTo15 = 0;
  int distanceSwitch = 1;

  /**
   * Turns the gun right in small 10 degree turns. Robot moves every 15 turns.
   */
  public void run() {
    // set robot colors
    setAllColors(Color.ORANGE);
    setBulletColor(Color.RED);
    setScanColor(Color.gray);

    // gun movement independent from robot
    setAdjustGunForRobotTurn(true);

    // get battlefield dimensions, used to determine fire power ratio
    width = getBattleFieldWidth();
    height = getBattleFieldHeight();
    across = Math.sqrt((width * width) + (height * height));

    while (true) {
      turnGunRight(10);
      countTo15++;
      // move every 15 turns
      if (countTo15 == 15) {
        move1();
        countTo15 = 0;
      }

    }
  }

  /**
   * Robot fires using power proportional to the targets distance. Tries to re-acquire and shoot
   * enemies.
   * 
   * @param e the scanned robot
   */
  public void onScannedRobot(ScannedRobotEvent e) {
    // determine how much power to use
    double ratio = 1 - (e.getDistance() / across);
    // fire at full power if close enough
    if (e.getDistance() < 150) {
      fire(3);
    }
    // fire a ratio times full power if not close enough
    else {
      fire(ratio * 3);
    }
    // scan for robots in the near radius
    scan();
    if (e.getDistance() < (across / 2)) {
      turnGunLeft(20);
    }
    else if (e.getDistance() < across - (across / 4)) {
      turnGunLeft(10);
    }
    else {
      turnGunLeft(5);
    }

  }

  /**
   * Robot shoots in direction of clash with another robot at full power.
   * 
   * @param e the robot that hits this robot
   */
  public void onHitRobot(HitRobotEvent e) {
    double direction = e.getBearing();
    if (direction < 0 && direction > -45) {
      turnGunLeft(Math.abs(direction));
      fire(3);
    }
    else if (direction >= 0 && direction < 45) {
      turnGunRight(direction);
      fire(3);
    }

  }

  /**
   * Track when this robot hits a target.
   * 
   * @param e the bullet
   */
  public void onBulletHit(BulletHitEvent e) {
    myHitCount++;
    myMissCount--;

  }

  /**
   * Tracks when a bullet misses. Robot moves for every 5 misses.
   * 
   * @param e the bullet that misses
   */
  public void onBulletMissed(BulletMissedEvent e) {
    myMissCount++;
    if (myMissCount % 5 == 0) {
      move2();
    }

  }

  /**
   * Tracks when hit by a bullet. Robot moves for every 2 hits.
   * 
   * @param e the bullet that hits this robot
   */
  public void onHitByBullet(HitByBulletEvent e) {
    hitCount++;
    if (hitCount % 2 == 0) {
      move2();
    }
  }

  /**
   * Robot moves ahead a short distance and turns a short radius.
   */
  public void move1() {
    ahead(75);
    turnRight(45);
  }

  /**
   * Robot turns left or right and moves ahead based upon a movement counter.
   */
  public void move2() {
    if (distanceSwitch == 0) {
      turnRight(45);
      ahead(across / 5);
      distanceSwitch = 1;
    }
    else {
      turnLeft(45);
      ahead(across / 10);
      distanceSwitch = 0;
    }
  }

  /**
   * Victory dance.
   * 
   * @param e win event, it is negligible
   */
  public void onWin(WinEvent e) {
    turnRight(90);
    setBodyColor(Color.black);
    setGunColor(Color.cyan);
    setRadarColor(Color.MAGENTA);
    turnRight(270);
  }

}